<!DOCTYPE html>
<html lang="en">
<head>
  <title>Vert.x Shell - Vert.x</title>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta content="width=device-width, initial-scale=1.0" name="viewport">
  <meta content="Vert.x is a tool-kit for building reactive applications on the JVM." name="description">
  <link href="http://vertx.io/stylesheets/docs.css" media="screen" rel="stylesheet">
  <link href="http://vertx.io/stylesheets/font-awesome.min.css" media="screen" rel="stylesheet">
  <link href="http://vertx.io/javascripts/styles/rainbow.min.css" media="screen" rel="stylesheet">
  <!-- IE 6-8 support of HTML 5 elements -->
  <!--[if lt IE 9]>
  <script src="http://static.jboss.org/theme/js/libs/html5/pre3.6/html5.min.js"></script>
  <![endif]-->

  <link rel="apple-touch-icon" sizes="57x57" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-57x57.png">
  <link rel="apple-touch-icon" sizes="60x60" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-60x60.png">
  <link rel="apple-touch-icon" sizes="72x72" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-72x72.png">
  <link rel="apple-touch-icon" sizes="76x76" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-76x76.png">
  <link rel="apple-touch-icon" sizes="114x114" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-114x114.png">
  <link rel="apple-touch-icon" sizes="120x120" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-120x120.png">
  <link rel="apple-touch-icon" sizes="144x144" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-144x144.png">
  <link rel="apple-touch-icon" sizes="152x152" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-152x152.png">
  <link rel="apple-touch-icon" sizes="180x180" href="http://vertx.io/assets/favicons/vertx-favicon-7/apple-touch-icon-180x180.png">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-32x32.png" sizes="32x32">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/android-chrome-192x192.png" sizes="192x192">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-96x96.png" sizes="96x96">
  <link rel="icon" type="image/png" href="http://vertx.io/assets/favicons/vertx-favicon-7/favicon-16x16.png" sizes="16x16">
  <link rel="manifest" href="http://vertx.io/assets/favicons/vertx-favicon-7/manifest.json">
  <link rel="mask-icon" href="http://vertx.io/assets/favicons/vertx-favicon-7/safari-pinned-tab.svg" color="#5bbad5">
  <meta name="msapplication-TileColor" content="#7d3194">
  <meta name="msapplication-TileImage" content="http://vertx.io/assets/favicons/vertx-favicon-7/mstile-144x144.png">
  <meta name="theme-color" content="#ffffff">

  <link href="http://fonts.googleapis.com/css?family=Ubuntu:400,500,700,400italic" rel="stylesheet" type="text/css">
  <link rel="alternate" type="application/rss+xml" title="RSS"
     href="http://vertx.io/feed.xml">
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
      (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
      m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', 'UA-30144458-1', 'auto');
    ga('create', 'UA-71153120-1', 'auto', 'tracker');
    ga('send', 'pageview');
    ga('tracker.send', 'pageview');
  </script>
</head>
<body>

<a href="http://www.reactivemanifesto.org/" id="reactive-manifesto-banner">
  <img style="border: 0; position: fixed; right: 0; top:0; z-index: 9000"
    src="http://d379ifj7s9wntv.cloudfront.net/reactivemanifesto/images/ribbons/we-are-reactive-black-right.png">
</a>

<a id="skippy" class="sr-only sr-only-focusable" href="#content"><div class="container"><span class="skiplink-text">Skip to main content</span></div></a>

<header class="navbar navbar-default navbar-static-top" id="top" role="banner">
  <div class="container">
    <div class="navbar-header">
      <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#vertx-navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a href="http://vertx.io/" class="navbar-brand"><img alt="Brand" src="http://vertx.io/assets/logo-sm.png"></a>
    </div>
    <nav class="collapse navbar-collapse" id="vertx-navbar-collapse">
      <ul class="nav navbar-nav navbar-right">
        <li><a href="http://vertx.io/download/">Download</a></li>
        <li><a href="http://vertx.io/docs/">Documentation</a></li>
        <li><a href="https://github.com/vert-x3/wiki/wiki">Wiki</a></li>
        <li><a href="http://vertx.io/community/">Community</a></li>
        <li><a href="http://vertx.io/materials/">Materials</a></li>
        <li><a href="http://vertx.io/blog/">Blog</a></li>        
      </ul>
    </nav>
  </div>
</header>



  <div class="page-header" id="content">
    <div class="container">
      <div class="row">
        <div class="col-sm-12">
          <h1>Vert.x Shell</h1>
          
        </div>
      </div>
    </div>
  </div>




<div id="content">
  <div class="container docs-content">
    <div class="row">
      <div class="col-sm-12 col-md-push-9 col-md-3 hidden-xs hidden-sm">
        <div id="sidebar" data-spy="affix">
          <ul class="sectlevel1">
<li><a href="#_using_vert_x_shell">Using Vert.x Shell</a>
<ul class="sectlevel2">
<li><a href="#_shell_service">Shell service</a></li>
<li><a href="#_programmatic_service">Programmatic service</a></li>
</ul>
</li>
<li><a href="#_authentication">Authentication</a></li>
<li><a href="#_telnet_term_configuration">Telnet term configuration</a></li>
<li><a href="#_ssh_term_configuration">SSH term configuration</a></li>
<li><a href="#_http_term_configuration">HTTP term configuration</a></li>
<li><a href="#_keymap_configuration">Keymap configuration</a></li>
<li><a href="#_base_commands">Base commands</a></li>
<li><a href="#_extending_vert_x_shell">Extending Vert.x Shell</a>
<ul class="sectlevel2">
<li><a href="#_command_arguments">Command arguments</a></li>
<li><a href="#_terminal_usage">Terminal usage</a></li>
<li><a href="#_shell_session">Shell session</a></li>
<li><a href="#_process_termination">Process termination</a></li>
<li><a href="#_process_events">Process events</a></li>
<li><a href="#_command_completion">Command completion</a></li>
</ul>
</li>
<li><a href="#_shell_server">Shell server</a></li>
<li><a href="#_terminal_servers">Terminal servers</a>
<ul class="sectlevel2">
<li><a href="#_ssh_term">SSH term</a></li>
<li><a href="#_telnet_term">Telnet term</a></li>
<li><a href="#_http_term">HTTP term</a></li>
</ul>
</li>
<li><a href="#_command_discovery">Command discovery</a></li>
<li><a href="#_command_pack">Command pack</a></li>
</ul>
        </div>
      </div>
      <div class="col-sm-12 col-md-pull-3 col-md-9">
        <div class="toc hidden-md hidden-lg">
          <h2>Table of Contents</h2>
          <ul class="sectlevel1">
<li><a href="#_using_vert_x_shell">Using Vert.x Shell</a>
<ul class="sectlevel2">
<li><a href="#_shell_service">Shell service</a></li>
<li><a href="#_programmatic_service">Programmatic service</a></li>
</ul>
</li>
<li><a href="#_authentication">Authentication</a></li>
<li><a href="#_telnet_term_configuration">Telnet term configuration</a></li>
<li><a href="#_ssh_term_configuration">SSH term configuration</a></li>
<li><a href="#_http_term_configuration">HTTP term configuration</a></li>
<li><a href="#_keymap_configuration">Keymap configuration</a></li>
<li><a href="#_base_commands">Base commands</a></li>
<li><a href="#_extending_vert_x_shell">Extending Vert.x Shell</a>
<ul class="sectlevel2">
<li><a href="#_command_arguments">Command arguments</a></li>
<li><a href="#_terminal_usage">Terminal usage</a></li>
<li><a href="#_shell_session">Shell session</a></li>
<li><a href="#_process_termination">Process termination</a></li>
<li><a href="#_process_events">Process events</a></li>
<li><a href="#_command_completion">Command completion</a></li>
</ul>
</li>
<li><a href="#_shell_server">Shell server</a></li>
<li><a href="#_terminal_servers">Terminal servers</a>
<ul class="sectlevel2">
<li><a href="#_ssh_term">SSH term</a></li>
<li><a href="#_telnet_term">Telnet term</a></li>
<li><a href="#_http_term">HTTP term</a></li>
</ul>
</li>
<li><a href="#_command_discovery">Command discovery</a></li>
<li><a href="#_command_pack">Command pack</a></li>
</ul>
        </div>
        <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x Shell is a command line interface for the Vert.x runtime available from regular
terminals using different protocols.</p>
</div>
<div class="paragraph">
<p>Vert.x Shell provides a variety of commands for interacting live with Vert.x services.</p>
</div>
<div class="paragraph">
<p>Vert.x Shell can be extended with custom commands in any language supported by Vert.x</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_using_vert_x_shell">Using Vert.x Shell</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x Shell is a Vert.x Service and can be started programmatically via the <code><a href="../../apidocs/io/vertx/ext/shell/ShellService.html">ShellService</a></code>
or deployed as a service.</p>
</div>
<div class="sect2">
<h3 id="_shell_service">Shell service</h3>
<div class="paragraph">
<p>The shell can be started as a service directly either from the command line or as a the Vert.x deployment:</p>
</div>
<div class="listingblock">
<div class="title">Starting a shell service available via Telnet</div>
<div class="content">
<pre class="prettyprint highlight"><code>vertx run -conf '{"telnetOptions":{"port":5000}}' maven:io.vertx:vertx-shell:3.3.3</code></pre>
</div>
</div>
<div class="paragraph">
<p>or</p>
</div>
<div class="listingblock">
<div class="title">Starting a shell service available via SSH</div>
<div class="content">
<pre class="prettyprint highlight"><code># create a key pair for the SSH server
keytool -genkey -keyalg RSA -keystore ssh.jks -keysize 2048 -validity 1095 -dname CN=localhost -keypass secret -storepass secret
# create the auth config
echo user.admin=password &gt; auth.properties
# start the shell
vertx run -conf '{"sshOptions":{"port":4000,"keyPairOptions":{"path":"ssh.jks","password":"secret"},"authOptions":{"provider":"shiro","config":{"properties_path":"file:auth.properties"}}}}' maven:io.vertx:vertx-shell:3.3.3</code></pre>
</div>
</div>
<div class="paragraph">
<p>or</p>
</div>
<div class="listingblock">
<div class="title">Starting a shell service available via HTTP</div>
<div class="content">
<pre class="prettyprint highlight"><code># create a certificate for the HTTP server
keytool -genkey -keyalg RSA -keystore keystore.jks -keysize 2048 -validity 1095 -dname CN=localhost -keypass secret -storepass secret
# create the auth config
echo user.admin=password &gt; auth.properties
vertx run -conf '{"httpOptions":{"port":8080,"ssl":true,"keyStoreOptions":{"path":"keystore.jks","password":"secret"},"authOptions":{"provider":""shiro,"config":{"properties_path":"file:auth.properties"}}}}' maven:io.vertx:vertx-shell:3.3.3</code></pre>
</div>
</div>
<div class="paragraph">
<p>You can also deploy this service inside your own verticle:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">vertx.deployVerticle("maven:{maven-groupId}:{maven-artifactId}:{maven-version}",
    new DeploymentOptions().setConfig(
        new JsonObject().put("telnetOptions",
            new JsonObject().
                put("host", "localhost").
                put("port", 4000))
    )
);</code></pre>
</div>
</div>
<div class="paragraph">
<p>or</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">vertx.deployVerticle("maven:{maven-groupId}:{maven-artifactId}:{maven-version}",
    new DeploymentOptions().setConfig(new JsonObject().
            put("sshOptions", new JsonObject().
                put("host", "localhost").
                put("port", 5000).
                put("keyPairOptions", new JsonObject().
                    put("path", "src/test/resources/ssh.jks").
                    put("password", "wibble")).
                put("authOptions", new JsonObject().
                    put("provider", "shiro").
                    put("config", new JsonObject().
                        put("properties_path", "file:/path/to/my/auth.properties"))))
    )
);</code></pre>
</div>
</div>
<div class="paragraph">
<p>or</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">vertx.deployVerticle("maven:{maven-groupId}:{maven-artifactId}:{maven-version}",
    new DeploymentOptions().setConfig(new JsonObject().
            put("httpOptions", new JsonObject().
                put("host", "localhost").
                put("port", 8080).
                put("ssl", true).
                put("keyPairOptions", new JsonObject().
                    put("path", "src/test/resources/server-keystore.jks").
                    put("password", "wibble")).
                put("authOptions", new JsonObject().
                    put("provider", "shiro").
                    put("config", new JsonObject().
                        put("properties_path", "file:/path/to/my/auth.properties"))))
    )
);</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
when Vert.x Shell is already on your classpath you can use <code>service:io.vertx.ext.shell</code> instead
or <code>maven:io.vertx:vertx-shell:3.3.3</code>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="_programmatic_service">Programmatic service</h3>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/ShellService.html">ShellService</a></code> takes care of starting an instance of Vert.x Shell.</p>
</div>
<div class="paragraph">
<p>Starting a shell service available via SSH:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ShellService service = ShellService.create(vertx,
    new ShellServiceOptions().setSSHOptions(
        new SSHTermOptions().
            setHost("localhost").
            setPort(5000).
            setKeyPairOptions(new JksOptions().
                    setPath("server-keystore.jks").
                    setPassword("wibble")
            ).
            setAuthOptions(new ShiroAuthOptions().
                    setType(ShiroAuthRealmType.PROPERTIES).
                    setConfig(new JsonObject().
                        put("properties_path", "file:/path/to/my/auth.properties"))
            )
    )
);
service.start();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Starting a shell service available via Telnet:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ShellService service = ShellService.create(vertx,
    new ShellServiceOptions().setTelnetOptions(
        new TelnetTermOptions().
            setHost("localhost").
            setPort(4000)
    )
);
service.start();</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/term/TelnetTermOptions.html">TelnetTermOptions</a></code> extends the Vert.x Core <code>NetServerOptions</code> as the Telnet server
implementation is based on a <code>NetServer</code>.</p>
</div>
<div class="admonitionblock caution">
<table>
<tr>
<td class="icon">
<div class="title">Caution</div>
</td>
<td class="content">
Telnet does not provide any authentication nor encryption at all.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Starting a shell service available via HTTP:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ShellService service = ShellService.create(vertx,
    new ShellServiceOptions().setHttpOptions(
        new HttpTermOptions().
            setHost("localhost").
            setPort(8080)
    )
);
service.start();</code></pre>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_authentication">Authentication</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The SSH and HTTP connectors provide both authentication built on top of <em>vertx-auth</em> with the following supported
providers:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>shiro</em> : provides <code>.properties</code> and <em>LDAP</em> backend as seen in the ShellService presentation</p>
</li>
<li>
<p><em>jdbc</em> : JDBC backend</p>
</li>
<li>
<p><em>mongo</em> : MongoDB backend</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>These options can be created directly using directly <code><a href="../../apidocs/io/vertx/ext/auth/AuthOptions.html">AuthOptions</a></code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/auth/shiro/ShiroAuthOptions.html">ShiroAuthOptions</a></code> for Shiro</p>
</li>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/auth/jdbc/JDBCAuthOptions.html">JDBCAuthOptions</a></code> for JDBC</p>
</li>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/auth/mongo/MongoAuthOptions.html">MongoAuthOptions</a></code> for Mongo</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>As for external service configuration in Json, the <code>authOptions</code> uses the <code>provider</code> property to distinguish:</p>
</div>
<div class="listingblock">
<div class="content">
<pre>{
  ...
  "authOptions": {
    "provider":"shiro",
    "config": {
      "properties_path":"file:auth.properties"
    }
  }
  ...
}</pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_telnet_term_configuration">Telnet term configuration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Telnet terms are configured by <code><a href="../../apidocs/io/vertx/ext/shell/ShellServiceOptions.html#setTelnetOptions-io.vertx.ext.shell.term.TelnetTermOptions-">setTelnetOptions</a></code>,
the <code><a href="../../apidocs/io/vertx/ext/shell/term/TelnetTermOptions.html">TelnetTermOptions</a></code> extends the <code><a href="../../apidocs/io/vertx/core/net/NetServerOptions.html">NetServerOptions</a></code> so they
have the exact same configuration.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_ssh_term_configuration">SSH term configuration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>SSH terms are configured by <code><a href="../../apidocs/io/vertx/ext/shell/ShellServiceOptions.html#setSSHOptions-io.vertx.ext.shell.term.SSHTermOptions-">setSSHOptions</a></code>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/SSHTermOptions.html#setPort-int-">setPort</a></code>: port</p>
</li>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/SSHTermOptions.html#setHost-java.lang.String-">setHost</a></code>: host</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Only username/password authentication is supported at the moment, it can be configured with property file
or LDAP, see Vert.x Auth for more info:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/SSHTermOptions.html#setAuthOptions-io.vertx.ext.auth.AuthOptions-">setAuthOptions</a></code>: configures user authentication</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The server key configuration reuses the key pair store configuration scheme provided by <em>Vert.x Core</em>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/SSHTermOptions.html#setKeyPairOptions-io.vertx.core.net.JksOptions-">setKeyPairOptions</a></code>: set <code>.jks</code> key pair store</p>
</li>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/SSHTermOptions.html#setPfxKeyPairOptions-io.vertx.core.net.PfxOptions-">setPfxKeyPairOptions</a></code>: set <code>.pfx</code> key pair store</p>
</li>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/SSHTermOptions.html#setPemKeyPairOptions-io.vertx.core.net.PemKeyCertOptions-">setPemKeyPairOptions</a></code>: set <code>.pem</code> key pair store</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="title">Deploying the Shell Service on SSH with Mongo authentication</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">vertx.deployVerticle("maven:{maven-groupId}:{maven-artifactId}:{maven-version}",
    new DeploymentOptions().setConfig(new JsonObject().
            put("sshOptions", new JsonObject().
                put("host", "localhost").
                put("port", 5000).
                put("keyPairOptions", new JsonObject().
                    put("path", "src/test/resources/ssh.jks").
                    put("password", "wibble")).
                put("authOptions", new JsonObject().
                    put("provider", "mongo").
                    put("config", new JsonObject().
                        put("connection_string", "mongodb://localhost:27018"))))
    )
);</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Running the Shell Service on SSH with Mongo authentication</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ShellService service = ShellService.create(vertx,
    new ShellServiceOptions().setSSHOptions(
        new SSHTermOptions().
            setHost("localhost").
            setPort(5000).
            setKeyPairOptions(new JksOptions().
                    setPath("server-keystore.jks").
                    setPassword("wibble")
            ).
            setAuthOptions(new MongoAuthOptions().setConfig(new JsonObject().
                    put("connection_string", "mongodb://localhost:27018"))
            )
    )
);
service.start();</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Deploying the Shell Service on SSH with JDBC authentication</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">vertx.deployVerticle("maven:{maven-groupId}:{maven-artifactId}:{maven-version}",
    new DeploymentOptions().setConfig(new JsonObject().
            put("sshOptions", new JsonObject().
                put("host", "localhost").
                put("port", 5000).
                put("keyPairOptions", new JsonObject().
                    put("path", "src/test/resources/ssh.jks").
                    put("password", "wibble")).
                put("authOptions", new JsonObject().
                    put("provider", "jdbc").
                    put("config", new JsonObject()
                        .put("url", "jdbc:hsqldb:mem:test?shutdown=true")
                        .put("driver_class", "org.hsqldb.jdbcDriver"))))
    )
);</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Running the Shell Service on SSH with JDBC authentication</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ShellService service = ShellService.create(vertx,
    new ShellServiceOptions().setSSHOptions(
        new SSHTermOptions().
            setHost("localhost").
            setPort(5000).
            setKeyPairOptions(new JksOptions().
                    setPath("server-keystore.jks").
                    setPassword("wibble")
            ).
            setAuthOptions(new JDBCAuthOptions().setConfig(new JsonObject()
                    .put("url", "jdbc:hsqldb:mem:test?shutdown=true")
                    .put("driver_class", "org.hsqldb.jdbcDriver"))
            )
    )
);
service.start();</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_http_term_configuration">HTTP term configuration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>HTTP terms are configured by <code><a href="../../apidocs/io/vertx/ext/shell/ShellServiceOptions.html#setHttpOptions-io.vertx.ext.shell.term.HttpTermOptions-">setHttpOptions</a></code>, the http options
extends the <code><a href="../../apidocs/io/vertx/core/http/HttpServerOptions.html">HttpServerOptions</a></code> so they expose the exact same configuration.</p>
</div>
<div class="paragraph">
<p>In addition there are extra options for configuring an HTTP term:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/HttpTermOptions.html#setAuthOptions-io.vertx.ext.auth.AuthOptions-">setAuthOptions</a></code>: configures user authentication</p>
</li>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/HttpTermOptions.html#setSockJSHandlerOptions-io.vertx.ext.web.handler.sockjs.SockJSHandlerOptions-">setSockJSHandlerOptions</a></code>: configures SockJS</p>
</li>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/HttpTermOptions.html#setSockJSPath-java.lang.String-">setSockJSPath</a></code>: the SockJS path in the router</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="title">Deploying the Shell Service on HTTP with Mongo authentication</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">vertx.deployVerticle("maven:{maven-groupId}:{maven-artifactId}:{maven-version}",
    new DeploymentOptions().setConfig(new JsonObject().
            put("httpOptions", new JsonObject().
                put("host", "localhost").
                put("port", 8080).
                put("ssl", true).
                put("keyPairOptions", new JsonObject().
                    put("path", "src/test/resources/server-keystore.jks").
                    put("password", "wibble")).
                put("authOptions", new JsonObject().
                    put("provider", "mongo").
                    put("config", new JsonObject().
                        put("connection_string", "mongodb://localhost:27018"))))
    )
);</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Running the Shell Service on HTTP with Mongo authentication</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ShellService service = ShellService.create(vertx,
    new ShellServiceOptions().setHttpOptions(
        new HttpTermOptions().
            setHost("localhost").
            setPort(8080).
            setAuthOptions(new MongoAuthOptions().setConfig(new JsonObject().
                    put("connection_string", "mongodb://localhost:27018"))
            )
    )
);
service.start();</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Deploying the Shell Service on HTTP with JDBC authentication</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">vertx.deployVerticle("maven:{maven-groupId}:{maven-artifactId}:{maven-version}",
    new DeploymentOptions().setConfig(new JsonObject().
            put("httpOptions", new JsonObject().
                put("host", "localhost").
                put("port", 8080).
                put("ssl", true).
                put("keyPairOptions", new JsonObject().
                    put("path", "src/test/resources/server-keystore.jks").
                    put("password", "wibble")).
                put("authOptions", new JsonObject().
                    put("provider", "jdbc").
                    put("config", new JsonObject()
                        .put("url", "jdbc:hsqldb:mem:test?shutdown=true")
                        .put("driver_class", "org.hsqldb.jdbcDriver"))))
    )
);</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Running the Shell Service on HTTP with JDBC authentication</div>
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ShellService service = ShellService.create(vertx,
    new ShellServiceOptions().setHttpOptions(
        new HttpTermOptions().
            setHost("localhost").
            setPort(8080).
            setAuthOptions(new JDBCAuthOptions().setConfig(new JsonObject()
                    .put("url", "jdbc:hsqldb:mem:test?shutdown=true")
                    .put("driver_class", "org.hsqldb.jdbcDriver"))
            )
    )
);
service.start();</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_keymap_configuration">Keymap configuration</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The shell uses a default keymap configuration that can be overriden using the <code>inputrc</code> property of the various
term configuration object:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/TelnetTermOptions.html#setIntputrc-java.lang.String-">setIntputrc</a></code></p>
</li>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/SSHTermOptions.html#setIntputrc-java.lang.String-">setIntputrc</a></code></p>
</li>
<li>
<p><code><a href="../../apidocs/io/vertx/ext/shell/term/HttpTermOptions.html#setIntputrc-java.lang.String-">setIntputrc</a></code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>inputrc</code> must point to a file available via the classloader or the filesystem.</p>
</div>
<div class="paragraph">
<p>The <code>inputrc</code> only function bindings and the available functions are:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>backward-char</em></p>
</li>
<li>
<p><em>forward-char</em></p>
</li>
<li>
<p><em>next-history</em></p>
</li>
<li>
<p><em>previous-history</em></p>
</li>
<li>
<p><em>backward-delete-char</em></p>
</li>
<li>
<p><em>backward-delete-char</em></p>
</li>
<li>
<p><em>backward-word</em></p>
</li>
<li>
<p><em>end-of-line</em></p>
</li>
<li>
<p><em>beginning-of-line</em></p>
</li>
<li>
<p><em>delete-char</em></p>
</li>
<li>
<p><em>delete-char</em></p>
</li>
<li>
<p><em>complete</em></p>
</li>
<li>
<p><em>accept-line</em></p>
</li>
<li>
<p><em>accept-line</em></p>
</li>
<li>
<p><em>kill-line</em></p>
</li>
<li>
<p><em>backward-word</em></p>
</li>
<li>
<p><em>forward-word</em></p>
</li>
<li>
<p><em>backward-kill-word</em></p>
</li>
</ul>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Extra functions can be added, however this is done by implementing functions of the <code>Term.d</code> project on which
Vert.x Shell is based, for instance the <a href="https://github.com/termd/termd/blob/c1629623c8a3add4bde7778640bf8cc233a7c98f/src/examples/java/examples/readlinefunction/ReverseFunction.java">reverse function</a>
can be implemented and then declared in a <code>META-INF/services/io.termd.core.readline.Function</code> to be loaded by the shell.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_base_commands">Base commands</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To find out the available commands you can use the <em>help</em> builtin command:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Verticle commands</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>verticle-ls: list all deployed verticles</p>
</li>
<li>
<p>verticle-undeploy: undeploy a verticle</p>
</li>
<li>
<p>verticle-deploy: deployes a verticle</p>
</li>
<li>
<p>verticle-factories: list all known verticle factories</p>
</li>
</ol>
</div>
</li>
<li>
<p>File system commands</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>ls</p>
</li>
<li>
<p>cd</p>
</li>
<li>
<p>pwd</p>
</li>
</ol>
</div>
</li>
<li>
<p>Bus commands</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>bus-tail: display all incoming messages on an event bus address</p>
</li>
<li>
<p>bus-send: send a message on the event bus</p>
</li>
</ol>
</div>
</li>
<li>
<p>Net commands</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>net-ls: list all available net servers, including HTTP servers</p>
</li>
</ol>
</div>
</li>
<li>
<p>Shared data commands</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>local-map-put</p>
</li>
<li>
<p>local-map-get</p>
</li>
<li>
<p>local-map-rm</p>
</li>
</ol>
</div>
</li>
<li>
<p>Various commands</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>echo</p>
</li>
<li>
<p>sleep</p>
</li>
<li>
<p>help</p>
</li>
<li>
<p>exit</p>
</li>
<li>
<p>logout</p>
</li>
</ol>
</div>
</li>
<li>
<p>Job control</p>
<div class="olist loweralpha">
<ol class="loweralpha" type="a">
<li>
<p>fg</p>
</li>
<li>
<p>bg</p>
</li>
<li>
<p>jobs</p>
</li>
</ol>
</div>
</li>
</ol>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
this command list should evolve in next releases of Vert.x Shell. Other Vert.x project may provide commands to extend
Vert.x Shell, for instance Dropwizard Metrics.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_extending_vert_x_shell">Extending Vert.x Shell</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x Shell can be extended with custom commands in any of the languages supporting code generation.</p>
</div>
<div class="paragraph">
<p>A command is created by the <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandBuilder.html#command-java.lang.String-">CommandBuilder.command</a></code> method: the command process handler is called
by the shell when the command is executed, this handler can be set with the <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandBuilder.html#processHandler-io.vertx.core.Handler-">processHandler</a></code>
method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">CommandBuilder builder = CommandBuilder.command("my-command");
builder.processHandler(process -&gt; {

  // Write a message to the console
  process.write("Hello World");

  // End the process
  process.end();
});

// Register the command
CommandRegistry registry = CommandRegistry.getShared(vertx);
registry.registerCommand(builder.build(vertx));</code></pre>
</div>
</div>
<div class="paragraph">
<p>After a command is created, it needs to be registed to a <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandRegistry.html">CommandRegistry</a></code>. The
command registry holds all the commands for a Vert.x instance.</p>
</div>
<div class="paragraph">
<p>A command is registered until it is unregistered with the <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandRegistry.html#unregisterCommand-java.lang.String-">unregisterCommand</a></code>.
When a command is registered from a Verticle, this command is unregistered when this verticle is undeployed.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<div class="title">Note</div>
</td>
<td class="content">
Command callbacks are invoked in the <code>io.vertx.core.Context</code> when the command is registered in the
registry. Keep this in mind if you maintain state in a command.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html">CommandProcess</a></code> object can be used for interacting with the shell.</p>
</div>
<div class="sect2">
<h3 id="_command_arguments">Command arguments</h3>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html#args--">args</a></code> returns the command arguments:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">command.processHandler(process -&gt; {

  for (String arg : process.args()) {
    // Print each argument on the console
    process.write("Argument " + arg);
  }

  process.end();
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>Besides it is also possible to create commands using <code><a href="../../apidocs/io/vertx/core/cli/CLI.html">Vert.x CLI</a></code>: it makes easier to
write command line argument parsing:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><em>option</em> and <em>argument</em> parsing</p>
</li>
<li>
<p>argument <em>validation</em></p>
</li>
<li>
<p>generation of the command <em>usage</em></p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">CLI cli = CLI.create("my-command").
    addArgument(new Argument().setArgName("my-arg")).
    addOption(new Option().setShortName("m").setLongName("my-option"));
CommandBuilder command = CommandBuilder.command(cli);
command.processHandler(process -&gt; {

  CommandLine commandLine = process.commandLine();

  String argValue = commandLine.getArgumentValue(0);
  String optValue = commandLine.getOptionValue("my-option");
  process.write("The argument is " + argValue + " and the option is " + optValue);

  process.end();
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>When an option named <em>help</em> is added to the CLI object, the shell will take care of generating the command usage
when the option is activated:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">CLI cli = CLI.create("my-command").
    addArgument(new Argument().setArgName("my-arg")).
    addOption(new Option().setArgName("help").setShortName("h").setLongName("help"));
CommandBuilder command = CommandBuilder.command(cli);
command.processHandler(process -&gt; {
  // ...
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>When the command executes the <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html">process</a></code> is provided for interacting
with the shell. A <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html">CommandProcess</a></code> extends <code><a href="../../apidocs/io/vertx/ext/shell/term/Tty.html">Tty</a></code>
which is used for interacting with the terminal.</p>
</div>
</div>
<div class="sect2">
<h3 id="_terminal_usage">Terminal usage</h3>
<div class="sect3">
<h4 id="_terminal_i_o">terminal I/O</h4>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/term/Tty.html#stdinHandler-io.vertx.core.Handler-">stdinHandler</a></code> handler is used to be notified when the terminal
receives data, e.g the user uses his keyboard:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">tty.stdinHandler(data -&gt; {
  System.out.println("Received " + data);
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>A command can use the <code><a href="../../apidocs/io/vertx/ext/shell/term/Tty.html#write-java.lang.String-">write</a></code> to write to the standard output.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">tty.write("Hello World");</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_terminal_size">Terminal size</h4>
<div class="paragraph">
<p>The current terminal size can be obtained using <code><a href="../../apidocs/io/vertx/ext/shell/term/Tty.html#width--">width</a></code> and
<code><a href="../../apidocs/io/vertx/ext/shell/term/Tty.html#height--">height</a></code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">tty.write("Current terminal size: (" + tty.width() + ", " + tty.height() + ")");</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_resize_event">Resize event</h4>
<div class="paragraph">
<p>When the size of the terminal changes the <code><a href="../../apidocs/io/vertx/ext/shell/term/Tty.html#resizehandler-io.vertx.core.Handler-">resizehandler</a></code>
is called, the new terminal size can be obtained with <code><a href="../../apidocs/io/vertx/ext/shell/term/Tty.html#width--">width</a></code> and
<code><a href="../../apidocs/io/vertx/ext/shell/term/Tty.html#height--">height</a></code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">tty.resizehandler(v -&gt; {
  System.out.println("terminal resized : " + tty.width() + " " + tty.height());
});</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_terminal_type">Terminal type</h4>
<div class="paragraph">
<p>The terminal type is useful for sending escape codes to the remote terminal: <code><a href="../../apidocs/io/vertx/ext/shell/term/Tty.html#type--">type</a></code>
returns the current terminal type, it can be null if the terminal has not advertised the value.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">System.out.println("terminal type : " + tty.type());</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_shell_session">Shell session</h3>
<div class="paragraph">
<p>The shell is a connected service that naturally maintains a session with the client, this session can be
used in commands to scope data. A command can get the session with <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html#session--">session</a></code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">command.processHandler(process -&gt; {

  Session session = process.session();

  if (session.get("my_key") == null) {
    session.put("my key", "my value");
  }

  process.end();
});</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_process_termination">Process termination</h3>
<div class="paragraph">
<p>Calling <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html#end--">end</a></code> ends the current process. It can be called directly
in the invocation of the command handler or any time later:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">command.processHandler(process -&gt; {
  Vertx vertx = process.vertx();

  // Set a timer
  vertx.setTimer(1000, id -&gt; {

    // End the command when the timer is fired
    process.end();
  });
});</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_process_events">Process events</h3>
<div class="paragraph">
<p>A command can subscribe to a few process events.</p>
</div>
<div class="sect3">
<h4 id="_interrupt_event">Interrupt event</h4>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html#interruptHandler-io.vertx.core.Handler-">interruptHandler</a></code> is called when the process
is interrupted, this event is fired when the user press <em>Ctrl+C</em> during the execution of a command. This handler can
be used for interrupting commands <em>blocking</em> the CLI and gracefully ending the command process:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">command.processHandler(process -&gt; {
  Vertx vertx = process.vertx();

  // Every second print a message on the console
  long periodicId = vertx.setPeriodic(1000, id -&gt; {
    process.write("tick\n");
  });

  // When user press Ctrl+C: cancel the timer and end the process
  process.interruptHandler(v -&gt; {
    vertx.cancelTimer(periodicId);
    process.end();
  });
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>When no interrupt handler is registered, pressing <em>Ctrl+C</em> will have no effect on the current process and the event
will be delayed and will likely be handled by the shell, like printing a new line on the console.</p>
</div>
</div>
<div class="sect3">
<h4 id="_suspend_resume_events">Suspend/resume events</h4>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html#suspendHandler-io.vertx.core.Handler-">suspendHandler</a></code> is called when the process
is running and the user press <em>Ctrl+Z</em>, the command is <em>suspended</em>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the command can receive the suspend event when it has registered an handler for this event</p>
</li>
<li>
<p>the command will not receive anymore data from the standard input</p>
</li>
<li>
<p>the shell prompt the user for input</p>
</li>
<li>
<p>the command can receive interrupts event or end events</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html#resumeHandler-io.vertx.core.Handler-">resumeHandler</a></code> is called when the process
is resumed, usually when the user types <em>fg</em>:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the command can receive the resume event when it has registered an handler for this event</p>
</li>
<li>
<p>the command will receive again data from the standard input when it has registered an stdin handler</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">command.processHandler(process -&gt; {

  // Command is suspended
  process.suspendHandler(v -&gt; {
    System.out.println("Suspended");
  });

  // Command is resumed
  process.resumeHandler(v -&gt; {
    System.out.println("Resumed");
  });
});</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="_end_events">End events</h4>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html#endHandler-io.vertx.core.Handler-">endHandler</a></code> (io.vertx.core.Handler)} is
called when the process is running or suspended and the command terminates, for instance the shell session is closed,
the command is <em>terminated</em>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">command.processHandler(process -&gt; {

  // Command terminates
  process.endHandler(v -&gt; {
    System.out.println("Terminated");
  });
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>The end handler is called even when the command invokes <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandProcess.html#end--">end</a></code>.</p>
</div>
<div class="paragraph">
<p>This handler is useful for cleaning up resources upon command termination, for instance closing a client or a timer.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_command_completion">Command completion</h3>
<div class="paragraph">
<p>A command can provide a completion handler when it wants to provide contextual command line interface completion.</p>
</div>
<div class="paragraph">
<p>Like the process handler, the <code><a href="../../apidocs/io/vertx/ext/shell/command/CommandBuilder.html#completionHandler-io.vertx.core.Handler-">completion
handler</a></code> is non blocking because the implementation may use Vert.x services, e.g the file system.</p>
</div>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/cli/Completion.html#lineTokens--">lineTokens</a></code> returns a list of <code><a href="../../apidocs/io/vertx/ext/shell/cli/CliToken.html">tokens</a></code>
from the beginning of the line to the cursor position. The list can be empty if the cursor when the cursor is at the
beginning of the line.</p>
</div>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/cli/Completion.html#rawLine--">rawLine</a></code> returns the current completed from the beginning
of the line to the cursor position, in raw format, i.e without any char escape performed.</p>
</div>
<div class="paragraph">
<p>Completion ends with a call to <code><a href="../../apidocs/io/vertx/ext/shell/cli/Completion.html#complete-java.util.List-">complete</a></code>.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_shell_server">Shell server</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The Shell service is a convenient facade for starting a preconfigured shell either programmatically or as a Vert.x service.
When more flexibility is needed, a <code><a href="../../apidocs/io/vertx/ext/shell/ShellServer.html">ShellServer</a></code> can be used instead of the service.</p>
</div>
<div class="paragraph">
<p>For instance the shell http term can be configured to use an existing router instead of starting its own http server.</p>
</div>
<div class="paragraph">
<p>Using a shell server requires explicit configuration but provides full flexiblity, a shell server is setup in a few
steps:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">ShellServer server = ShellServer.create(vertx); <b class="conum">(1)</b>

Router shellRouter = Router.router(vertx); <b class="conum">(2)</b>
router.mountSubRouter("/shell", shellRouter);
TermServer httpTermServer = TermServer.createHttpTermServer(vertx, router);

TermServer sshTermServer = TermServer.createSSHTermServer(vertx); <b class="conum">(3)</b>

server.registerTermServer(httpTermServer); <b class="conum">(4)</b>
server.registerTermServer(sshTermServer);

server.registerCommandResolver(CommandResolver.baseCommands(vertx)); <b class="conum">(5)</b>

server.listen(); <b class="conum">(6)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<ol>
<li>
<p>create a the shell server</p>
</li>
<li>
<p>create an HTTP term server mounted on an existing router</p>
</li>
<li>
<p>create an SSH term server</p>
</li>
<li>
<p>register term servers</p>
</li>
<li>
<p>register all base commands</p>
</li>
<li>
<p>finally start the shell server</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>Besides, the shell server can also be used for creating in process shell session: it provides a programmatic interactive shell.</p>
</div>
<div class="paragraph">
<p>In process shell session can be created with <code><a href="../../apidocs/io/vertx/ext/shell/ShellServer.html#createShell-io.vertx.ext.shell.term.Term-">createShell</a></code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">Shell shell = shellServer.createShell();</code></pre>
</div>
</div>
<div class="paragraph">
<p>The main use case is running or testing a command:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">Shell shell = shellServer.createShell();

// Create a job fo the command
Job job = shell.createJob("my-command 1234");

// Create a pseudo terminal
Pty pty = Pty.create();
pty.stdoutHandler(data -&gt; {
  System.out.println("Command wrote " + data);
});

// Run the command
job.setTty(pty.slave());
job.statusUpdateHandler(status -&gt; {
  System.out.println("Command terminated with status " + status);
});</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/term/Pty.html">Pty</a></code> pseudo terminal is the main interface for interacting with the command
when it&#8217;s running:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>uses standard input/output for writing or reading strings</p>
</li>
<li>
<p>resize the terminal</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/system/JobController.html#close-io.vertx.core.Handler-">close</a></code> closes the shell, it will terminate all jobs in the current shell
session.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_terminal_servers">Terminal servers</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Vert.x Shell also provides bare terminal servers for those who need to write pure terminal applications.</p>
</div>
<div class="paragraph">
<p>A <code><a href="../../apidocs/io/vertx/ext/shell/term/Term.html">Term</a></code> handler must be set on a term server before starting it. This handler will
handle each term when the user connects.</p>
</div>
<div class="paragraph">
<p>An <code><a href="../../apidocs/io/vertx/ext/auth/AuthOptions.html">AuthOptions</a></code> can be set on <code><a href="../../apidocs/io/vertx/ext/shell/term/SSHTermOptions.html">SSHTermOptions</a></code> and <code><a href="../../apidocs/io/vertx/ext/shell/term/HttpTermOptions.html">HttpTermOptions</a></code>.
Alternatively, an <code><a href="../../apidocs/io/vertx/ext/auth/AuthProvider.html">AuthProvider</a></code> can be <code><a href="../../apidocs/io/vertx/ext/shell/term/TermServer.html#authProvider-io.vertx.ext.auth.AuthProvider-">set</a></code>
directly on the term server before starting it.</p>
</div>
<div class="sect2">
<h3 id="_ssh_term">SSH term</h3>
<div class="paragraph">
<p>The terminal server <code><a href="../../apidocs/io/vertx/ext/shell/term/Term.html">Term</a></code> handler accepts incoming terminal connections.
When a remote terminal connects, the <code><a href="../../apidocs/io/vertx/ext/shell/term/Term.html">Term</a></code> can be used to interact with connected
terminal.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">TermServer server = TermServer.createSSHTermServer(vertx, new SSHTermOptions().setPort(5000).setHost("localhost"));
server.termHandler(term -&gt; {
  term.stdinHandler(line -&gt; {
    term.write(line);
  });
});
server.listen();</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/term/Term.html">Term</a></code> is also a <code><a href="../../apidocs/io/vertx/ext/shell/term/Tty.html">Tty</a></code>, this section explains
how to use the tty.</p>
</div>
</div>
<div class="sect2">
<h3 id="_telnet_term">Telnet term</h3>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">TermServer server = TermServer.createTelnetTermServer(vertx, new TelnetTermOptions().setPort(5000).setHost("localhost"));
server.termHandler(term -&gt; {
  term.stdinHandler(line -&gt; {
    term.write(line);
  });
});
server.listen();</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="_http_term">HTTP term</h3>
<div class="paragraph">
<p>The <code><a href="../../apidocs/io/vertx/ext/shell/term/TermServer.html#createHttpTermServer-io.vertx.core.Vertx-">TermServer.createHttpTermServer</a></code> method creates an HTTP term server, built
on top of Vert.x Web using the SockJS protocol.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">TermServer server = TermServer.createHttpTermServer(vertx, new HttpTermOptions().setPort(5000).setHost("localhost"));
server.termHandler(term -&gt; {
  term.stdinHandler(line -&gt; {
    term.write(line);
  });
});
server.listen();</code></pre>
</div>
</div>
<div class="paragraph">
<p>An HTTP term can start its own HTTP server, or it can reuse an existing Vert.x Web <code><a href="../../apidocs/io/vertx/ext/web/Router.html">Router</a></code>.</p>
</div>
<div class="paragraph">
<p>The shell can be found at <code>/shell.html</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">TermServer server = TermServer.createHttpTermServer(vertx, router, new HttpTermOptions().setPort(5000).setHost("localhost"));
server.termHandler(term -&gt; {
  term.stdinHandler(line -&gt; {
    term.write(line);
  });
});
server.listen();</code></pre>
</div>
</div>
<div class="paragraph">
<p>The later option is convenient when the HTTP shell is integrated in an existing HTTP server.</p>
</div>
<div class="paragraph">
<p>The HTTP term server by default is configured for serving:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>the <code>shell.html</code> page</p>
</li>
<li>
<p>the <code><a href="https://github.com/chjj/term.js/">term.js</a></code> client library</p>
</li>
<li>
<p>the <code>vertxshell.js</code> client library</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>vertxshell.js</code> integrates <code>term.js</code> is the client side part of the HTTP term.</p>
</div>
<div class="paragraph">
<p>It integrates <code>term.js</code> with SockJS and needs the URL of the HTTP term server endpoint:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-javascript" data-lang="javascript">window.addEventListener('load', function () {
  var url = 'http://localhost/shell';
  new VertxTerm(url, {
    cols: 80,
    rows: 24
   });
 });</code></pre>
</div>
</div>
<div class="paragraph">
<p>Straight websockets can also be used, if so, the remote term URL should be suffixed with <code>/websocket</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-javascript" data-lang="javascript">window.addEventListener('load', function () {
  var url = 'ws://localhost/shell/websocket';
  new VertxTerm(url, {
    cols: 80,
    rows: 24
   });
 });</code></pre>
</div>
</div>
<div class="paragraph">
<p>For customization purpose these resources can be copied and customized, they are available in the Vert.x Shell
jar under the <code>io.vertx.ext.shell</code> packages.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_command_discovery">Command discovery</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The command discovery can be used when new commands need to be added to Vert.x without an explicit registration.</p>
</div>
<div class="paragraph">
<p>For example, the <em>Dropwizard</em> metrics service, adds specific metrics command to the shell service on the fly.</p>
</div>
<div class="paragraph">
<p>It can be achieved via the <code>java.util.ServiceLoader</code> of a <code><a href="../../apidocs/io/vertx/ext/shell/spi/CommandResolverFactory.html">CommandResolverFactory</a></code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public class CustomCommands implements CommandResolverFactory {

  public void resolver(Vertx vertx, Handler&lt;AsyncResult&lt;CommandResolver&gt;&gt; resolverHandler) {
    resolverHandler.handler(() -&gt; Arrays.asList(myCommand1, myCommand2));
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The <code>resolver</code> method is async, because the resolver may need to wait some condition before commands
are resolved.</p>
</div>
<div class="paragraph">
<p>The shell service discovery using the service loader mechanism:</p>
</div>
<div class="listingblock">
<div class="title">The service provider file <code>META-INF/services/io.vertx.ext.shell.spi.CommandResolverFactory</code></div>
<div class="content">
<pre class="prettyprint highlight"><code>my.CustomCommands</code></pre>
</div>
</div>
<div class="paragraph">
<p>This is only valid for the <code><a href="../../apidocs/io/vertx/ext/shell/ShellService.html">ShellService</a></code>. <code><a href="../../apidocs/io/vertx/ext/shell/ShellServer.html">ShellServer</a></code>
don&#8217;t use this mechanism.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="_command_pack">Command pack</h2>
<div class="sectionbody">
<div class="paragraph">
<p>A command pack is a jar that provides new Vert.x Shell commands.</p>
</div>
<div class="paragraph">
<p>Such jar just need to be present on the classpath and it is discovered by Vertx. Shell.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="prettyprint highlight"><code class="language-java" data-lang="java">public class CommandPackExample implements CommandResolverFactory {

  @Override
  public void resolver(Vertx vertx, Handler&lt;AsyncResult&lt;CommandResolver&gt;&gt; resolveHandler) {
    List&lt;Command&gt; commands = new ArrayList&lt;&gt;();

    // Add commands
    commands.add(Command.create(vertx, JavaCommandExample.class));

    // Add another command
    commands.add(CommandBuilder.command("another-command").processHandler(process -&gt; {
      // Handle process
    }).build(vertx));

    // Resolve with the commands
    resolveHandler.handle(Future.succeededFuture(() -&gt; commands));
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The command pack uses command discovery mechanism, so it needs the descriptor:</p>
</div>
<div class="listingblock">
<div class="title"><code>META-INF/services/io.vertx.ext.shell.spi.CommandResolverFactory</code> descriptor</div>
<div class="content">
<pre class="prettyprint highlight"><code>examples.pack.CommandPackExample</code></pre>
</div>
</div>
</div>
</div>

        

        
          <div id="footer">
            <div id="footer-text">
              
                Last updated 2016-09-12 08:38:04 CEST
              
              
            </div>
          </div>
        
      </div>
    </div>
  </div>
</div>

<footer>
  <div class="container">
    <div class="row">
      <div class="col-xs-6 col-sm-3 col-md-3 col-lg-2">
        <h2>Vert.x</h2>
        <ul class="list-unstyled">
          <li><a href="http://vertx.io/">Home</a></li>
          <li><a href="http://vertx.io/download/">Download</a></li>
          <li><a href="http://vertx.io/docs/">Documentation</a></li>
          <li><a href="https://github.com/vert-x3/wiki/wiki">Wiki</a></li>
          <li><a href="http://vertx.io/blog/">Blog</a></li>
          <li><a href="http://vertx.io/vertx2/" class="vertx-2-link">Vert.x 2</a></li>
        </ul>
      </div>
      <div class="col-xs-6 col-sm-3 col-md-3 col-lg-2">
        <h2>Community</h2>
        <ul class="list-unstyled">
          <li><a href="http://vertx.io/community/">Help &amp; Contributors</a></li>
          <li><a href="http://vertx.io/materials/">Learning materials</a></li>
          <li><a href="https://groups.google.com/forum/?fromgroups#!forum/vertx">User Group</a></li>
          <li><a href="https://groups.google.com/forum/?fromgroups#!forum/vertx-dev">Developer Group</a></li>
        </ul>
      </div>

      <div class="col-xs-12 col-sm-6 col-lg-offset-2 col-md-6 copyright">
        <p>Vert.x is open source and dual licensed under the <a href="https://www.eclipse.org/org/documents/epl-v10.php">Eclipse Public License 1.0</a> and <a href="https://www.apache.org/licenses/LICENSE-2.0.html">Apache License 2.0</a>.</p>
        <p>This website is licensed under the <a href="http://creativecommons.org/licenses/by-sa/3.0/">CC BY-SA 3.0 License</a>.<br>
        Design by <a href="http://www.michel-kraemer.com">Michel Kr&auml;mer</a>. <a href="http://www.entypo.com">Entypo pictograms</a> by Daniel Bruce.</p>
        <div class="row">
          <div class="col-xs-12 col-lg-offset-1 col-md-5">
            <a href="http://eclipse.org">
            <img class="logo eclipse-logo" src="http://vertx.io/assets/eclipse_logo_grey_small.png" width="204" height="48">
            </a>
          </div>
          <div class="col-xs-12 col-md-offset-2 col-lg-offset-0 col-md-5">
            <a href="http://cloudbees.com">
            <img class="logo cloudbees-logo" src="http://vertx.io/assets/Button-Built-on-CB-1-grey.png" width="180" height="48">
           </a>
          </div>
          <div class="col-xs-12 col-md-offset-2 col-lg-offset-1 col-md-5 jprofiler">
            <a href="http://www.ej-technologies.com/products/jprofiler/overview.html"
            style="text-decoration:none">
            <img class="logo jprofiler-logo" src="http://vertx.io/assets/jprofiler-logo.png" width="48" height="48"><span class="jprofiler-logo">&nbsp; JPROFILER</span>
            </a>
          </div>
        </div>
      </div>
    </div>
  </div>
</footer>

<script src="http://static.jboss.org/theme/js/libs/jquery/jquery-1.9.1.min.js"></script>
<script src="http://vertx.io/javascripts/bootstrap.min.js"></script>
<script src="http://vertx.io/javascripts/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>



<script src="http://vertx.io/javascripts/sidebar.js"></script>


</body>
</html>
